package dao

import (
	"crypto/rand"
	"encoding/base64"
	"encoding/binary"
	"fmt"
	"strings"
	"time"
)

// GetInvitationCode 生成包含当前时间信息的邀请码
func GetCutInvitationCode(userId, goodsId, joinId int64) (string, error) {
	// 获取当前时间（纳秒精度）
	now := time.Now().UnixNano()

	// 创建数据缓冲区：时间(8) + 数字1(4) + 数字2(4) + 数字3(4) + 随机数(8)
	data := make([]byte, 28)

	// 写入时间戳（8字节）
	binary.BigEndian.PutUint64(data[0:8], uint64(now))

	// 写入三个数字（各4字节）
	binary.BigEndian.PutUint32(data[8:12], uint32(userId))
	binary.BigEndian.PutUint32(data[12:16], uint32(goodsId))
	binary.BigEndian.PutUint32(data[16:20], uint32(joinId))

	// 添加随机字节增加熵（8字节）
	if _, err := rand.Read(data[20:28]); err != nil {
		return "", err
	}

	// 使用URL安全的Base64编码
	encoded := base64.URLEncoding.EncodeToString(data)

	// 移除填充字符，使字符串更整洁
	return strings.TrimRight(encoded, "="), nil
}

// ParseInvitationCode 解析邀请码，返回用户ID、商品ID、参与记录id、创建时间及可能的错误
func ParseCutInvitationCode(invitationCode string) (time.Time, int, int, int, error) {
	// 添加填充字符以便解码
	if pad := len(invitationCode) % 4; pad != 0 {
		invitationCode += strings.Repeat("=", 4-pad)
	}

	// Base64解码
	data, err := base64.URLEncoding.DecodeString(invitationCode)
	if err != nil {
		return time.Time{}, 0, 0, 0, err
	}

	if len(data) < 20 {
		return time.Time{}, 0, 0, 0, fmt.Errorf("invalid encoded string length")
	}

	// 解析时间戳
	timestamp := int64(binary.BigEndian.Uint64(data[0:8]))
	createTime := time.Unix(0, timestamp)

	// 解析三个数字
	userId := int(binary.BigEndian.Uint32(data[8:12]))
	goodsId := int(binary.BigEndian.Uint32(data[12:16]))
	activityId := int(binary.BigEndian.Uint32(data[16:20]))

	return createTime, userId, goodsId, activityId, nil
}

// GetGroupInvitationCode 生成拼团邀请码
func GetGroupInvitationCode(userId, groupId int64) (string, error) {
	// 获取当前时间（纳秒精度）
	now := time.Now().UnixNano()

	// 创建数据缓冲区：时间(8) + 用户ID(4) + 拼团ID(4) + 随机数(8)
	data := make([]byte, 24)

	// 写入时间戳（8字节）
	binary.BigEndian.PutUint64(data[0:8], uint64(now))

	// 写入用户ID和拼团ID（各4字节）
	binary.BigEndian.PutUint32(data[8:12], uint32(userId))
	binary.BigEndian.PutUint32(data[12:16], uint32(groupId))

	// 添加随机字节增加熵（8字节）
	if _, err := rand.Read(data[16:24]); err != nil {
		return "", err
	}

	// 使用URL安全的Base64编码
	encoded := base64.URLEncoding.EncodeToString(data)

	// 移除填充字符，使字符串更整洁
	return strings.TrimRight(encoded, "="), nil
}

// ParseGroupInvitationCode 解析拼团邀请码，返回用户ID、拼团ID、创建时间及可能的错误
func ParseGroupInvitationCode(invitationCode string) (time.Time, int64, int64, error) {
	// 添加填充字符以便解码
	if pad := len(invitationCode) % 4; pad != 0 {
		invitationCode += strings.Repeat("=", 4-pad)
	}

	// Base64解码
	data, err := base64.URLEncoding.DecodeString(invitationCode)
	if err != nil {
		return time.Time{}, 0, 0, err
	}

	if len(data) < 16 {
		return time.Time{}, 0, 0, fmt.Errorf("invalid encoded string length")
	}

	// 解析时间戳
	timestamp := int64(binary.BigEndian.Uint64(data[0:8]))
	createTime := time.Unix(0, timestamp)

	// 解析用户ID和拼团ID
	userId := int64(binary.BigEndian.Uint32(data[8:12]))
	groupId := int64(binary.BigEndian.Uint32(data[12:16]))

	return createTime, userId, groupId, nil
}
